/*
    3D Office Environment
    Copyright (C) 2011  Till Merker

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.

*/

#ifndef OFFICEENV_H
#define OFFICEENV_H

#include <GL/gl.h>
#include <X11/X.h>

namespace Ogre {
    class Root;
    class SceneManager;
    class Camera;
    class Viewport;
    class RenderWindow;
    class GLTexture;
    class RenderTexture;
    class SceneNode;
    class Material;
    class RaySceneQuery;
    class SphereSceneQuery;
    class Vector3;
    class Entity;
}

namespace OfficeEnv {
    
#define IA_FORWARD 1
#define IA_BACKWARD 2
#define IA_TURN 4
#define IA_STEPLEFT 8
#define IA_STEPRIGHT 16
#define IA_UPDOWN 32

const int MAX_DESKTOPS = 4;

enum CameraAnimation { CA_None, CA_Switch, CA_ZoomOut };

class BaseOfficeScene;

/* Main class for 3DOE. This is the API used by the KDE/compiz plugins */
class OfficeEnv
{
  private:         
    Ogre::Root *mRoot;

    /* OGRE's main render window */
    Ogre::RenderWindow *mWindow;

    Ogre::GLTexture *mDesktopTexture[MAX_DESKTOPS];

    /* Target texture which we render to */
    Ogre::RenderTexture *mRenderTexture;
    Ogre::GLTexture *mTargetTexture;
    
    /* Viewport */ 
    Ogre::Viewport *mViewport;
    
    /* The office scene */
    BaseOfficeScene *mScene;

    /* Members for saving/restoring GL state */
    GLfloat mProjectionMatrix[16];
    GLfloat mModelviewMatrix[16];
    GLfloat mTextureMatrix[16];
    GLint mFramebuffer;
    GLint mArrayBuffer;
    GLint mElementArrayBuffer;
    GLint mTextureEnvMode;
    
    /* Initialization */
    void initResources(char *office);
    void initTextures(int width, int height, int numDesktops);
    void initScene();
    
    /* Saving/restoring GL state before/after OGRE calls */
    void saveGLState();
    void restoreGLState();   

  public:
    OfficeEnv();
    virtual ~OfficeEnv();
    
    /* Starting/shutting down the renderer and the office scene. <office> is the name of the scene to use */
    void startup(int width, int height, int numDesktops, char *office);
    void shutdown();
    
    /* Renders one frame */
    void renderFrame();
    
    /* Processes an input action. forward/sidestep should be either +1 ior -1, 
     * yaw and pitch are delta values in radians */ 
    void inputAction(int forward, int sidestep, float yaw, float pitch);
    
    /* Get texture ID of a desktop  */
    GLuint getTexture(int desktop);
    /* Get the target render texture */
    GLuint getTargetTexture();
    
    /* Start an animation */
    void startAnimation(CameraAnimation animation, int param);
    CameraAnimation getCurrentAnimation();
    
    /* return the number of the desktop the user is currently looking at, -1 if none */
    int getTargetedDesktop();
       
};

}

#endif // OFFICEENV_H
